package cn.xuewei.controller;

import cn.xuewei.mapper.UserMapper;
import cn.xuewei.pojo.dto.UserLoginDTO;
import cn.xuewei.pojo.dto.UserRegDTO;
import cn.xuewei.pojo.dto.UserUpdateDTO;
import cn.xuewei.pojo.entity.User;
import cn.xuewei.pojo.vo.UserAdminVO;
import cn.xuewei.pojo.vo.UserChatVO;
import cn.xuewei.pojo.vo.UserVO;
import cn.xuewei.response.ResultVO;
import cn.xuewei.response.StatusCode;
import cn.xuewei.utils.CurPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/v1/users/")
public class UserController {
    @Autowired(required = false)
    UserMapper userMapper;

    @Autowired
    PasswordEncoder passwordEncoder;

    @RequestMapping("reg")
    public ResultVO reg(@RequestBody UserRegDTO userRegDTO) {
        UserVO userVO = userMapper.selectByUsername(userRegDTO.getUsername());
        if (userVO != null) {
            return new ResultVO(StatusCode.USERNAME_EXIST);
        }
        User user = new User();
        BeanUtils.copyProperties(userRegDTO, user);
        user.setCreated(new Date());
        user.setIsAdmin(0);//默认不是管理员
        user.setBalance(new BigDecimal(0));
        user.setImgUrl("/imgs/icon.jpg");
        //密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        userMapper.insert(user);
        return new ResultVO(StatusCode.REG_SUCCESS);
    }

    @Autowired
    AuthenticationManager manager;

    @RequestMapping("login")
    public ResultVO login(@RequestBody UserLoginDTO userLoginDTO) {
        //认证
        Authentication result = manager.authenticate(new UsernamePasswordAuthenticationToken(
                userLoginDTO.getUsername(), userLoginDTO.getPassword()));
        //将认证结果保存到Security上下文 让Security框架记录
        SecurityContextHolder.getContext().setAuthentication(result);
        CurPool.curUserPool.put(userLoginDTO.getUsername(),userMapper.selectChatVOByUsername(userLoginDTO.getUsername()));
        return ResultVO.ok(result.getPrincipal());
    }

    @RequestMapping("logout")
    public void logout() {
        SecurityContextHolder.clearContext();
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        if(CurPool.sessionPool != null ||CurPool.curUserPool != null ||CurPool.webSockets != null ){
            if (CurPool.curUserPool != null) {
                CurPool.curUserPool.remove(name);
            }
            UserChatVO user = userMapper.selectChatVOByUsername(name);
            CurPool.sessionPool.remove(user.getId());
            CurPool.webSockets.remove(user.getId());
            System.out.println("【websocket消息】连接断开，总数为:"+CurPool.webSockets.size());
        }

    }


    @RequestMapping("/update")
    public ResultVO update(@RequestBody UserUpdateDTO userUpdateDTO) {
        User user = new User();
        BeanUtils.copyProperties(userUpdateDTO, user);
        userMapper.update(user);
        return ResultVO.ok();
    }

    /**
     * admin界面显示用户列表
     * @return
     */
    @PreAuthorize("hasAnyAuthority('ADMIN')")
    @RequestMapping()
    public ResultVO list(){
        List<UserAdminVO> list = userMapper.select();
        return ResultVO.ok(list);
    }

    /**
     * admin页面设置管理员权限
     * @param userid
     * @param isAdmin
     * @return
     */
    @PreAuthorize("hasAnyAuthority('ADMIN')")
    @RequestMapping("/{userid}/{isAdmin}/change")
    public ResultVO change(@PathVariable Long userid,@PathVariable Integer isAdmin){
        User user = new User();
        user.setUserid(userid);
        user.setIsAdmin(isAdmin);
        userMapper.update(user);
        return ResultVO.ok();
    }

    /**
     * 在admin页面删除用户
     * @param userid
     * @return
     */
    @PreAuthorize("hasAnyAuthority('ADMIN')")
    @RequestMapping("/{userid}/delete")
    public ResultVO delete(@PathVariable Long userid){
        userMapper.deleteById(userid);
        return ResultVO.ok();
    }

    @RequestMapping("/balance/{user_id}")
    public ResultVO getBalance(@PathVariable Long user_id){
        return ResultVO.ok(userMapper.getBalance(user_id));
    }

    @RequestMapping("/updatebalance/{user_id}/{balance}")
    public ResultVO updateBalance(@PathVariable Long user_id,@PathVariable double balance){
        userMapper.updateBalance(user_id,balance);
        return ResultVO.ok();
    }

    /**
     * 管理员充值
     * @param id
     * @param balance
     * @return
     */
    @PreAuthorize("hasAnyAuthority('ADMIN')")
    @RequestMapping("{id}/adminBalance/{balance}")
    public ResultVO adminBalance(@PathVariable Long id,@PathVariable double balance){
        userMapper.adminBalance(id,balance);
        return ResultVO.ok();
    }
}
